package com.test.example.collections

import java.lang.StringBuilder

/*
any, all, none      https://play.kotlinlang.org/byExample/05_Collections/05_existential
 */

fun main() {
    //Function any
    //Function any returns true if the collection contains at least one element that matches the given predicate.
    val numbers = listOf(1, -2, 3, -4, 5, -6, 7)

    val anyNegative = numbers.any { it < 0 }             //  只要有一个小于 0 的 返回 true

    val anyGT6 = numbers.any { it > 6 }                  // 只要有一个大于 6 的 返回 true

    println("anyNegative  = $anyNegative ,  anyGT6 = $anyGT6")
    //anyNegative  = true ,  anyGT6 = true


    //Function all
    //Function all returns true if all elements in collection match the given predicate.
    val allEven = numbers.all { it % 2 == 0 }
    val allLess6 = numbers.all { it < 6 }
    println("allEven  = $allEven ,  allLess6 = $allLess6")
    //allEven  = false ,  allLess6 = false


    //Function none
    //Function none returns true if there are no elements that match the given predicate in the collection.
    val noneEven = numbers.none { it % 2 == 1 }
    val noneLess6 = numbers.none { it > 6 }
    println("noneEven  = $noneEven ,  noneLess6 = $noneLess6")
    //noneEven  = false ,  noneLess6 = false


    //count
    //count functions returns either the total number of elements in a collection or the number of elements matching the given predicate.
    val totalCount = numbers.count()
    val evenCount = numbers.count { it % 2 == 0 }
    println("totalCount  = $totalCount ,  evenCount = $evenCount")
    //totalCount  = 7 ,  evenCount = 3


    //partition
    //The partition function splits the original collection into a pair of lists using a given predicate:
    //Elements for which the predicate is true.
    //Elements for which the predicate is false.
    val evenOdd = numbers.partition { it % 2 == 0 }
    val (positives, negatives) = numbers.partition { it > 0 }
    println("evenOdd  = $evenOdd ,  positives = $positives  ， negatives = $negatives")
    //evenOdd  = ([-2, -4, -6], [1, 3, 5, 7]) ,  positives = [1, 3, 5, 7]  ， negatives = [-2, -4, -6]

    val name1 = "niiiib"
    val name11 = name1.encryptName()
    val num1 = "5962345610"
    val num11 = num1.encryptNumber()

   val num112 =  num11.decryptNumber()

    println("name11 = $name11 , num11 = $num11   num112 = $num112")

    //name11 = FnEiDiCiBiAb , num11 = FJGCDEFGBA   num112 = 5962345610





}


/*

处理规则：
姓名：每个字符签名添加了一个字符，空白字符除外
号码：0123456789替换为ABCDEFGHIJ

 */


private fun String?.encryptName(): String? {
    if (this == null) {
        return null
    }
    val charArray = this.toCharArray()
    val size = charArray.size
    val nameChars = CharArray(size * 2)
    var indexChar = 0
    charArray.forEachIndexed { index, char ->
        if (!Character.isWhitespace(char)) {
            nameChars[indexChar++] = letters[(size - index - 1) % 26]
        }
        nameChars[indexChar++] = char
    }
    return nameChars.concatToString(0, indexChar)
}

private fun String?.encryptNumber(): String? {
    if (this == null) {
        return null
    }
    val charArray = this.replace("\\s".toRegex(), "").toCharArray()
    charArray.forEachIndexed { index, char ->
        if (Character.isDigit(char)) {
            charArray[index] = letters[char.toString().toInt()]
        }
    }
    return charArray.concatToString()
}

private fun String?.decryptNumber():String?{
    if (this == null || this.length >= letters.size) {
        return  this
    }
    val sb = StringBuilder()
    this.forEachIndexed{
        index, c ->
        sb.append(letters.indexOf(c))
    }
    return sb.toString()
}

private val letters = listOf(
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
)